package com.siashan.toolkit.sms.aliyun;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.siashan.toolkit.sms.core.entity.*;
import com.siashan.toolkit.sms.core.executor.AbstractSmsSendExecutor;
import com.siashan.toolkit.sms.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 阿里云短信通知执行器
 *
 * @author siashan
 * @since v1.0.1
 **/
@Slf4j
public class AliyunSmsSendExecutor extends AbstractSmsSendExecutor {


    private static final String OK = "OK";

    /**
     * 阿里云短信域名
     */
    private static final String DOMAIN = "dysmsapi.aliyuncs.com";

    /**
     * 版本号
     */
    private static final String VERSION = "2017-05-25";
    /**
     * SysAction
     */
    private static final String ACTION = "SendSms";
    /**
     * 参数：Message
     */
    private static final String PARAM_MESSAGE = "Message";
    /**
     * 参数：Code
     */
    private static final String PARAM_CODE = "Code";


    /**
     * Jackson系列化
     */
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 短信客户端
     */
    private final IAcsClient acsClient;


    /**
     * 阿里云短信配置
     */
    private AliyunSmsConfig aliyunSmsConfig;

    /**
     * 构造阿里云短信发送处理
     *
     * @param config 阿里云短信配置
     */
    public AliyunSmsSendExecutor(AliyunSmsConfig config) {
        super(config);
        this.aliyunSmsConfig = config;
        IClientProfile profile = DefaultProfile.getProfile(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
        acsClient = new DefaultAcsClient(profile);
    }
    /**
     * 构造阿里云短信发送处理
     *
     * @param config 阿里云短信配置
     */
    public AliyunSmsSendExecutor(AliyunSmsConfig config, Map<String, SmsTemplate> templateMap) {
        this(config);
        this.templateMap = templateMap;
    }

    /**
     * 构造阿里云短信发送处理
     *
     * @param config 阿里云短信配置
     */
    public AliyunSmsSendExecutor(AliyunSmsConfig config, Map<String, SmsTemplate> templateMap,SmsWhiteList whiteList) {
        this(config,templateMap);
        this.whiteList = whiteList;
    }

    /**
     * 构造阿里云短信发送处理
     *
     * @param config 阿里云短信配置
     */
    public AliyunSmsSendExecutor(AliyunSmsConfig config, Map<String, SmsTemplate> templateMap,SmsWhiteList whiteList,SmsFrequencyLimitConfig frequencyLimit) {
        this(config,templateMap,whiteList);
        this.frequencyLimit = frequencyLimit;
    }


    /**
     * 发送批量通知
     *
     * @param smsSendModel 通知参数
     * @return 是否发送成功
     */
    @Override
    public boolean doSend(SmsModel smsSendModel) {

        String paramString;
        try {
            paramString = objectMapper.writeValueAsString(smsSendModel.getParams());
        } catch (Exception e) {
            log.warn(e.getMessage(), e);
            return false;
        }
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain(DOMAIN);
        request.setSysVersion(VERSION);
        request.setSysAction(ACTION);
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", StringUtils.join(smsSendModel.getPhones(), ","));
        request.putQueryParameter("SignName", smsSendModel.getSignName());
        request.putQueryParameter("TemplateCode", smsSendModel.getTemplateId());
        request.putQueryParameter("TemplateParam", paramString);

        try {
            CommonResponse response = acsClient.getCommonResponse(request);
            JsonNode jsonNode = objectMapper.readValue(response.getData(), JsonNode.class);
            if (OK.equals(jsonNode.get(PARAM_CODE).asText())) {
                return true;
            }
            log.warn("sms send fail[code={}, message={}]", jsonNode.get(PARAM_CODE).asText(), jsonNode.get(PARAM_MESSAGE).asText());
        } catch (Exception e) {
            log.warn(e.getMessage(), e);
        }
        return false;
    }




    /**
     * 获取通道
     *
     * @return 通道
     */
    @Override
    public SmsChannel getChannel() {
        return SmsChannel.ALIYUN;
    }



}
